package org.toycode.logindemo.application.util;

import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * This class provides lookup for remote ejbs in glassfish v2.
 *
 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
 * @version 1.0.0.1, Aug 27, 2009
 */
final public class EjbUtil {

    private static final Properties props = new Properties();
    private static InitialContext ic;

    static {
        props.setProperty("java.naming.factory.initial",
                          "com.sun.enterprise.naming.SerialInitContextFactory");
        props.setProperty("java.naming.factory.url.pkgs",
                          "com.sun.enterprise.naming");
        props.setProperty("java.naming.factory.state",
                          "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");

        props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
        props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
        try {
            ic = new InitialContext(props);
        } catch (final NamingException ex) {
            Logger.getLogger(EjbUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Gets a ejb by the specified class.
     * @param <T> type of the ejb
     * @param clazz the specified class
     * @return the ejb correspondings to the specified clazz, if not found,
     * returns <code>null</code>
     * @throws RuntimeException
     */
    @SuppressWarnings("unchecked")
    public static synchronized <T> T getEjb(final Class<T> clazz) {
        final TimeOutThread timeoutThread =
                new TimeOutThread(3000L, new RuntimeException(
                "Remote service time out!"));

        T service = null;
        try {
            timeoutThread.start();
            service = (T) ic.lookup(clazz.getName());
            timeoutThread.cancel();

        } catch (final Exception ex) {
            return null;
        } finally {
            return service;
        }
    }
}
